package org.youyee.game.managers
{
	import org.youyee.game.event.AnimationEvent;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;

	/**
	 * 动画过渡管理器 
	 * @author youyeelu
	 * 
	 */	
	public class AnimationManager extends EventDispatcher
	{
		/**
		 * 时间间隔频率 
		 */		
		public static var TIME_RATE:int = 50;
		
		/**
		 * 每走动一格需要的时间 
		 */		
		public static var PATHNODE_TIME:int = 500;
		
		private var _objects:Array;
		private var _timer:Timer;
		private var _objectLayer:Sprite;
		
		/**
		 * 构造函数 
		 * @param objectLayer 物体层
		 * 
		 */		
		public function AnimationManager(objectLayer:Sprite)
		{
			super();
			
			_objects = [];
			this._timer = new Timer(TIME_RATE);
			this._objectLayer = objectLayer;
			
			addListener();
		}
		
		private function addListener():void
		{
			if (this._objectLayer)
			{
				this._objectLayer.addEventListener(AnimationEvent.REQUEST_MOVETO, handleRequestMoveTo);
				this._objectLayer.addEventListener(AnimationEvent.DROP_MOVING_OBJ, handleDropMovingObj);
			}
			
			this._timer.addEventListener(TimerEvent.TIMER, handleTimer);
		}
		
		private function removeListener():void
		{
			if (this._objectLayer)
			{
				this._objectLayer.removeEventListener(AnimationEvent.REQUEST_MOVETO, handleRequestMoveTo);
				this._objectLayer.removeEventListener(AnimationEvent.DROP_MOVING_OBJ, handleDropMovingObj);
			}
			
			if (this._timer)
			{
				this._timer.removeEventListener(TimerEvent.TIMER, handleTimer);
			}
		}
		
		private function handleDropMovingObj(e:AnimationEvent):void
		{
			var obj:DisplayObject = e.data as DisplayObject;
			
			if (obj)
			{
				removeObject(obj);
			}
		}
		
		private function handleRequestMoveTo(e:AnimationEvent):void
		{
			var info:Object = e.data;
			addObject(info.object, info.targetPoint, info.speed, info.completedHandler);
		}
		
		private function handleTimer(e:TimerEvent):void
		{
			var displayObj:DisplayObject;
			var targetPoint:Point;
			var restTimes:int;
			var info:Object;
			
			var x:Number;
			var y:Number;
			
			var len:int = this._objects.length;
			
			for (var i:int=0; i<len; ++i)
			{
				info = this._objects[i];
				displayObj = info.object as DisplayObject;
				targetPoint = info.targetPoint as Point;
				restTimes = info.restTimes;
				
				--restTimes;
				
				x = targetPoint.x - info.stepX * restTimes;
				y = targetPoint.y - info.stepY * restTimes;
				
				info.restTimes = restTimes;
				
				displayObj.x = x;
				displayObj.y = y;
				
				if (!restTimes)
				{
					this._objects.splice(i, 1);
					--i;
					--len;
					
					if (info.completedHandler)
					{
						info.completedHandler(displayObj);
					}
					
					dispatchEvent(new AnimationEvent(AnimationEvent.ANIMATION_COMPLETED, displayObj));
					clearRef(info);
				}
			}
		}
		
		/**
		 * 添加一个物体进来管理器 
		 * @param obj 物体
		 * @param targetPoint 目标位置
		 * @param speed 速度
		 * @param completedHandler 完成后的回调
		 * 
		 */		
		public function addObject(obj:DisplayObject, targetPoint:Point, speed:Number=1, completedHandler:Function=null):void
		{
			if (!hasObject(obj))
			{
				var t:int = speed * (PATHNODE_TIME / TIME_RATE);
				
				var info:Object = {
					object : obj,
					targetPoint : targetPoint,
					restTimes :  t,
					stepX : (targetPoint.x - obj.x) / t,
					stepY : (targetPoint.y - obj.y) / t,
					completedHandler : completedHandler
				};
				
				this._objects.push(info);
				
				if (!_timer.running)
				{
					_timer.start();
				}
			}
		}
		
		/**
		 * 是否存在此物体 
		 * @param obj 需要被检测的物体
		 * @return 
		 * 
		 */		
		public function hasObject(obj:DisplayObject):Boolean
		{
			var len:int = this._objects.length;
			
			for (var i:int=0; i<len; ++i)
			{
				if (this._objects[i].object == obj)
				{
					return true;
				}
			}
			
			return false;
		}
		
		/**
		 * 移除物体 
		 * @param obj 需要被移除的物体
		 * 
		 */		
		public function removeObject(obj:DisplayObject):void
		{
			var len:int = this._objects.length;
			
			for (var i:int=0; i<len; ++i)
			{
				if (this._objects[i].object == obj)
				{
					var info:Object = this._objects.splice(i, 1)[0];
					clearRef(info);
					break;
				}
			}
		}
		
		/**
		 * 移除掉所有的物体 
		 * 
		 */		
		public function removeAllObject():void
		{
			while (_objects.length)
			{
				removeObject(_objects[0].object as DisplayObject);
			}
		}
		
		private function clearRef(info:Object):void
		{
			for (var i:* in info)
			{
				info[i] = null;
			}
		}
		
		/**
		 * 销毁管理器 
		 * 
		 */		
		public function destroy():void
		{
			if (this._timer)
			{
				this._timer.stop();
			}
			
			removeAllObject();
			removeListener();
			
			this._objects = null;
			this._timer = null;
			this._objectLayer = null;
		}
	}
}